/*
 * Copyright 2014 OGIS-RI All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jp.co.ogis_ri.optaplanner.vehiclerouting;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.univocity.parsers.common.processor.BeanListProcessor;
import com.univocity.parsers.csv.CsvParser;
import com.univocity.parsers.csv.CsvParserSettings;

import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.Cargo;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.Depot;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.Location;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.SolutionParameter;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.Vehicle;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.VehicleRoutingSolution;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.core.ChainedTimeWindowedStep;

public class SolutionGenerator {

    public VehicleRoutingSolution createSolution() {

        long id = 0;

        List<ChainedTimeWindowedStep> chainedTimeWindowedStepList = new ArrayList<ChainedTimeWindowedStep>();

        List<Location> locationList = new ArrayList<Location>();
        List<Depot> depotList = new ArrayList<Depot>();
        List<Vehicle> vehicleList = new ArrayList<Vehicle>();

        //
        Location locationDummy = new Location();
        locationDummy.setId(id++);
        locationDummy.setLatitude(Double.parseDouble("34.7110545"));
        locationDummy.setLongitude(Double.parseDouble("135.6078796"));
        locationDummy.setName("Dummy");
        locationDummy.setAddress("Dummy");

        Depot depotDummy = new Depot();
        depotDummy.setId(id++);
        depotDummy.setLocation(locationDummy);

        Vehicle vehicleDummy = new Vehicle();
        vehicleDummy.setId(id++);
        vehicleDummy.setDummy(true);
        vehicleDummy.setDepot(depotDummy);

        locationList.add(locationDummy);
        depotList.add(depotDummy);
        vehicleList.add(vehicleDummy);

        // 車両
        for (int i = 0; i < 23; i++) {
            Location location = new Location();
            location.setId(id++);
            location.setLatitude(Double.parseDouble("34.7110545"));
            location.setLongitude(Double.parseDouble("135.6078796"));
            location.setName("大東営業所");
            location.setAddress("大阪府大東市新田旭町1-15");

            Depot depot = new Depot();
            depot.setId(id++);
            depot.setLocation(location);

            Vehicle vehicle = new Vehicle();
            vehicle.setId(id++);
            vehicle.setDepot(depot);
            vehicle.setReadyTime(21600);
            vehicle.setDueTime(54000);
            if (i < 7) {
                // 10t車
                vehicle.setCapacity(4800);
            } else if (6 < i && i < 17) {
                // 4t車
                vehicle.setCapacity(2500);

            } else {
                // 2t車
                vehicle.setCapacity(1500);
            }

            locationList.add(location);
            depotList.add(depot);
            vehicleList.add(vehicle);
        }

        // csvファイルより配送依頼データを取得する
        BeanListProcessor<Receiver> rowProcessor = new BeanListProcessor<Receiver>(Receiver.class);

        CsvParserSettings parserSettings = new CsvParserSettings();
        parserSettings.setProcessor(rowProcessor);
        parserSettings.setHeaderExtractionEnabled(true);

        CsvParser parser = new CsvParser(parserSettings);
        // parser.parse(getReader("C:\\Users\\li_yue\\Desktop\\order.csv"));
        parser.parse(new File("C:/Users/li_yue/Desktop/order.csv"), "UTF-8");

        // The BeanListProcessor provides a list of objects extracted from the
        // input.
        List<Receiver> receiverList = rowProcessor.getBeans();

        // 荷物
        for (int i = 0; i < receiverList.size(); i++) {

            Receiver receiver = receiverList.get(i);

            Location location = new Location();
            location.setId(id++);
            location.setLatitude(receiver.getLatitude());
            location.setLongitude(receiver.getLongitude());
            location.setName(receiver.getName());
            location.setOrderNo(receiver.getOrderNo());
            location.setAddress(receiver.getAddress());

            locationList.add(location);

            Cargo cargo = new Cargo();
            cargo.setId(id);
            cargo.setLocation(location);
            cargo.setSize(receiver.getSize().multiply(BigDecimal.valueOf(100)).intValue());

            cargo.setReadyTime(receiver.getReadyTime());
            cargo.setDueTime(receiver.getDueTime());

            cargo.setServiceDuration(1800);
            System.out.println(cargo.toString());

            chainedTimeWindowedStepList.add(cargo);
        }

/*        // 休憩
        for (int i = 0; i < 4; i++) {
            Break break1 = new Break();
            break1.setId(id++);
            break1.setReadyTime(2500);
            break1.setDueTime(7500);
            break1.setBreakTime(500);

            chainedTimeWindowedStepList.add(break1);
        }*/

        SolutionParameter solutionParameter = new SolutionParameter();
        solutionParameter.setCountAverage(300F / 4F);

        VehicleRoutingSolution solution = new VehicleRoutingSolution();
        solution.setId(id++);
        solution.setName("VehicleRoutingSolution");
        solution.setCargoList(chainedTimeWindowedStepList);
        solution.setDepotList(depotList);
        solution.setLocationList(locationList);
        solution.setVehicleList(vehicleList);
        solution.setSolutionParameter(solutionParameter);

        return solution;

    }
}
